package com.srmt.document.feishu.internal;

import com.srmt.feishu.client.FeishuClient;
import com.lark.oapi.service.docx.v1.model.*;
import com.srmt.document.exception.DocumentOperationException;
import com.srmt.document.feishu.internal.core.BlockContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 飞书索引解析器（重构版）
 * 
 * 基于BlockContext实现，遵循"一次获取，多次使用"原则。
 * 移除了持久化缓存，每个方法都基于最新的文档数据。
 * 
 * @author srmt
 * @since 2.0.0
 */
public class FeishuIndexResolver {
    
    private static final Logger logger = LoggerFactory.getLogger(FeishuIndexResolver.class);
    
    private final FeishuClient client;
    
    public FeishuIndexResolver(FeishuClient client) {
        if (client == null) {
            throw new IllegalArgumentException("客户端不能为null");
        }
        this.client = client;
    }
    
    /**
     * 计算在父Block中插入新Block的索引位置
     * 
     * @param documentId 文档ID
     * @param parentBlockId 父Block ID
     * @param anchorBlockId 锚点Block ID（可选，为null时追加到末尾）
     * @param afterAnchor 是否插入到锚点后面（true:后面, false:前面）
     * @return 正确的插入索引，-1表示追加到末尾
     * @throws DocumentOperationException 如果计算失败
     */
    public int resolveInsertIndex(String documentId, String parentBlockId, 
                                  String anchorBlockId, boolean afterAnchor) 
            throws DocumentOperationException {
        
        logger.debug("解析插入索引 - 文档: {}, parent: {}, anchor: {}, after: {}", 
                    documentId, parentBlockId, anchorBlockId, afterAnchor);
        
        // 如果没有锚点，追加到末尾
        if (anchorBlockId == null || anchorBlockId.isEmpty()) {
            logger.debug("没有锚点块,追加到末尾");
            return -1;
        }
        
        try {
            // 创建上下文（唯一的API调用）
            BlockContext context = new BlockContext(client, documentId);
            
            // 获取父Block
            Block parentBlock = context.getBlockById(parentBlockId);
            if (parentBlock == null) {
                logger.warn("父块未找到: {}", parentBlockId);
                return -1;
            }
            
            // 获取父Block的children
            String[] children = parentBlock.getChildren();
            if (children == null || children.length == 0) {
                logger.debug("父块没有子块,作为第一个子块追加");
                return 0;
            }
            
            // 在children中查找锚点Block的位置
            for (int i = 0; i < children.length; i++) {
                if (children[i].equals(anchorBlockId)) {
                    int insertIndex = afterAnchor ? i + 1 : i;
                    logger.debug("在索引处找到锚点 {}, insert index: {}", i, insertIndex);
                    return insertIndex;
                }
            }
            
            // 没找到锚点Block，可能锚点不是直接子节点
            logger.warn("锚点块{}在父块的子块列表中未找到,将追加到末尾", anchorBlockId);
            return -1;
            
        } catch (Exception e) {
            logger.error("解析插入索引失败: {}", e.getMessage());
            // 降级处理：返回-1追加到末尾
            return -1;
        }
    }
    
    /**
     * 验证索引是否在有效范围内
     * 
     * @param documentId 文档ID
     * @param parentBlockId 父Block ID
     * @param index 要验证的索引
     * @return true如果索引有效
     */
    public boolean validateIndex(String documentId, String parentBlockId, int index) {
        // -1 总是有效的（表示追加到末尾）
        if (index == -1) {
            return true;
        }
        
        try {
            // 创建上下文
            BlockContext context = new BlockContext(client, documentId);
            
            Block parentBlock = context.getBlockById(parentBlockId);
            if (parentBlock == null) {
                return false;
            }
            
            String[] children = parentBlock.getChildren();
            int maxIndex = (children != null) ? children.length : 0;
            
            // 索引可以是0到children.length（包含），允许插入到任何位置
            boolean valid = index >= 0 && index <= maxIndex;
            
            if (!valid) {
                logger.warn("无效 index {} for parent block with {} children", index, maxIndex);
            }
            
            return valid;
            
        } catch (Exception e) {
            logger.error("验证索引失败: {}", e.getMessage());
            return false;
        }
    }
    

    
    /**
     * 获取安全的插入索引
     * 如果计算失败或验证失败，返回-1（追加到末尾）
     * 
     * @param documentId 文档ID
     * @param parentBlockId 父Block ID
     * @param anchorBlockId 锚点Block ID
     * @param afterAnchor 是否插入到锚点后面
     * @return 安全的插入索引
     */
    public int getSafeInsertIndex(String documentId, String parentBlockId,
                                  String anchorBlockId, boolean afterAnchor) {
        try {
            int index = resolveInsertIndex(documentId, parentBlockId, anchorBlockId, afterAnchor);
            
            // 验证索引
            if (validateIndex(documentId, parentBlockId, index)) {
                return index;
            }
            
            logger.warn("索引验证失败,使用追加模式");
            return -1;
            
        } catch (Exception e) {
            logger.error("获取安全插入索引失败,使用追加模式: {}", e.getMessage());
            return -1;
        }
    }


}